package com.ssy.lingxi.platform.manage.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.CommonConstant;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.manage.ShopEnvironmentEnum;
import com.ssy.lingxi.common.constant.manage.ShopPropertyEnum;
import com.ssy.lingxi.common.constant.manage.ShopTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.platform.manage.api.model.dto.common.CommonIdListDTO;
import com.ssy.lingxi.platform.manage.api.model.vo.shop.ShopInnerVO;
import com.ssy.lingxi.platform.manage.api.model.vo.shop.ShopVO;
import com.ssy.lingxi.platform.manage.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.manage.entity.base.*;
import com.ssy.lingxi.platform.manage.model.request.shop.BiddingShopRequest;
import com.ssy.lingxi.platform.manage.model.request.shop.DoorTypeRequest;
import com.ssy.lingxi.platform.manage.model.request.shop.ShopListRequest;
import com.ssy.lingxi.platform.manage.model.request.shop.SiteIdAndEnvironmentRequest;
import com.ssy.lingxi.platform.manage.model.response.EnterpriseShopListResponse;
import com.ssy.lingxi.platform.manage.repository.ShopRepository;
import com.ssy.lingxi.platform.manage.repository.ShopRuleDetailRepository;
import com.ssy.lingxi.platform.manage.repository.SiteShopRepository;
import com.ssy.lingxi.platform.manage.service.IShopService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 商城 - 业务实现层
 *
 * @author fhj
 * @version 2.0.0
 * @date 2020/9/28
 */
@Slf4j
@Service
public class ShopServiceImpl implements IShopService {

    @Resource
    private ShopRepository shopRepository;
    @Resource
    private SiteShopRepository siteShopRepository;
    @Resource
    private IRedisStringUtils redisStringUtils;
    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private ShopRuleDetailRepository shopRuleDetailRepository;

    /**
     * 查询所有商城信息
     */
    @Override
    public Wrapper<List<ShopVO>> shopAll() {
        List<Shop> allByStateEquals = shopRepository.findAllByStateEquals(CommonConstant.State.STATE_START);
        List<ShopVO> list = new ArrayList<>();
        allByStateEquals.forEach(shop -> {
            ShopVO shopResponse = new ShopVO();
            BeanUtils.copyProperties(shop, shopResponse);
            list.add(shopResponse);
        });
        return Wrapper.success(list);
    }

    /**
     * 根据ID查询商城信息
     */
    @Override
    public Wrapper<ShopVO> shopDetails(Long id) {
        if (id == null) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_ID_DOES_NOT_EXIST);
        }
        Shop shop = shopRepository.findById(id).orElse(null);
        if (shop == null) {
            return Wrapper.fail(ResponseCode.NO_SHOP_FOUND_BASED_ON_ID);
        }
        ShopVO shopResponse = new ShopVO();
        BeanUtils.copyProperties(shop, shopResponse);
        return Wrapper.success(shopResponse);
    }

    /**
     * 根据站点id查询所有商城信息
     *
     * @param siteId 站点ID
     * @param type   1：店铺。 2：渠道。
     */
    @Override
    public Wrapper<List<Shop>> findShopsBySiteId(Long siteId, Integer type) {
        QShop qShop = QShop.shop;
        QSiteShop qSiteShop = QSiteShop.siteShop;
        QSite qSite = QSite.site;
        JPAQuery<Shop> query = jpaQueryFactory.select(qShop)
                .from(qShop).leftJoin(qSiteShop).on(qShop.id.eq(qSiteShop.shopId))
                .leftJoin(qSite).on(qSite.id.eq(qSiteShop.siteId))
                .where(qSite.id.eq(siteId));

        if (type != null) {

            query.where(type == 1 ? qShop.type.in(ShopTypeEnum.ENTERPRISE.getCode(), ShopTypeEnum.SCORE.getCode()) : qShop.type.in(ShopTypeEnum.CHANNEL.getCode(), ShopTypeEnum.CHANNEL_SELF.getCode(), ShopTypeEnum.CHANNEL_SCORE.getCode()));
        }
        List<Shop> list = query.fetch();
        return Wrapper.success(list);
    }

    /**
     * 根据商城类型查询商城信息
     *
     * @param shopType 商城类型：1.企业商城 2.积分商城 3.渠道商城 4.渠道自有商城 5.渠道积分商城
     */
    @Override
    public Wrapper<List<ShopVO>> shopAllByShopType(Integer shopType) {
        List<Shop> allByStateEquals = shopRepository.findAllByTypeEqualsAndStateEquals(shopType, CommonConstant.State.STATE_START);
        List<ShopVO> list = new ArrayList<>();
        allByStateEquals.forEach(shop -> {
            ShopVO shopResponse = new ShopVO();
            BeanUtils.copyProperties(shop, shopResponse);
            list.add(shopResponse);
        });
        return Wrapper.success(list);
    }

    /**
     * 根据商城类型和环境查询商城信息
     *
     * @param shopType    商城类型：1.企业商城 2.积分商城 3.渠道商城 4.渠道自有商城 5.渠道积分商城
     * @param environment 商城环境：1-web 2-H5 3-小程序 4-APP
     */
    @Override
    public Wrapper<List<ShopVO>> findAllByShopTypeAndEnvironment(Integer shopType, Integer environment) {
        if (shopType != null && environment != null) {
            List<Shop> allByStateEquals = shopRepository.findByTypeAndStateAndEnvironment(shopType, CommonConstant.State.STATE_START, environment);
            List<ShopVO> list = new ArrayList<>();
            allByStateEquals.forEach(shop -> {
                ShopVO shopResponse = new ShopVO();
                BeanUtils.copyProperties(shop, shopResponse);
                list.add(shopResponse);
            });
            return Wrapper.success(list);
        }

        return Wrapper.fail(ResponseCode.PARAMETER_CANNOT_BE_EMPTY);
    }

    /**
     * 根据站点ID和商城环境查询所有商城信息
     */
    @Override
    public Wrapper<List<Shop>> findShopsBySiteIdAndEnvironment(SiteIdAndEnvironmentRequest request) {
        //根据站点ID获取站点关联的商城
        List<SiteShop> siteShopList = siteShopRepository.findBySiteId(request.getSiteId());
        if (CollectionUtil.isEmpty(siteShopList)) {
            return Wrapper.success(new ArrayList<>());
        }

        //获取商城
        List<Shop> shopList = shopRepository.findAllByIdInAndEnvironmentAndState(
                siteShopList.stream().map(SiteShop::getShopId).collect(Collectors.toList()),
                request.getEnvironment(),
                CommonBooleanEnum.YES.getCode()
        );

        //拼装返回
        return Wrapper.success(shopList);
    }

    @Override
    @ApiOperation(value = "根据门户类型获取商城【店铺、渠道、采购、物流、加工】")
    public Wrapper<List<Shop>> findByDoorType(DoorTypeRequest request, HttpServletRequest httpServletRequest) {
        //获取请求头的站点ID, 根据站点ID获取关联的商城
        String site = httpServletRequest.getHeader("site");
        List<SiteShop> siteShopList = siteShopRepository.findBySiteId(Long.valueOf(site));
        if (CollectionUtil.isEmpty(siteShopList)) {
            return Wrapper.success(new ArrayList<>());
        }

        //获取商城
        List<Shop> shopList = shopRepository.findAllByIdInAndTypeInAndEnvironmentAndState(
                siteShopList.stream().map(SiteShop::getShopId).collect(Collectors.toList()),
                ShopTypeEnum.findShopTypeListByDoorType(request.getDoorType()),
                ShopEnvironmentEnum.WEB.getCode(),
                CommonBooleanEnum.YES.getCode()
        );

        return Wrapper.success(shopList);
    }

    @Override
    @ApiOperation(value = "根据当前登录会员类型获取商城")
    public Wrapper<List<Shop>> findByMemberType(UserLoginCacheDTO user) {
        List<Shop> shopList = new ArrayList<>();
        if (user.getMemberRoleType().equals(RoleTypeEnum.SERVICE_PROVIDER.getCode())) {
            if (user.getMemberType().equals(MemberTypeEnum.MERCHANT.getCode()) || user.getMemberType().equals(MemberTypeEnum.MERCHANT_PERSONAL.getCode())) {
                shopList = shopRepository.findAllByTypeAndState(
                        ShopTypeEnum.ENTERPRISE.getCode(),
                        CommonBooleanEnum.YES.getCode()
                );
            }
            if (user.getMemberType().equals(MemberTypeEnum.CHANNEL.getCode()) || user.getMemberType().equals(MemberTypeEnum.CHANNEL_PERSONAL.getCode())) {
                shopList = shopRepository.findAllByTypeInAndState(
                        Stream.of(ShopTypeEnum.CHANNEL.getCode(), ShopTypeEnum.CHANNEL_SELF.getCode()).collect(Collectors.toList()),
                        CommonBooleanEnum.YES.getCode()
                );
            }
        }

        return Wrapper.success(shopList);
    }

    /**
     * 初始化到redis
     */
    @Override
    public void initToRedis() {
        //先清除缓存
        redisStringUtils.del(Constants.REDIS_KEY_SHOP, Constants.REDIS_PLATFORM_MANAGE_INDEX);
        List<Shop> shopList = shopRepository.findByState(CommonConstant.State.STATE_START);

        if (shopList != null && !shopList.isEmpty()) {
            Map<String, String> map = new HashMap<>();
            shopList.stream().filter(shop -> shop.getSelf().equals(0)).forEach(shop -> map.put(String.valueOf(shop.getId()), JSONUtil.toJsonStr(shop)));
            if (map.size() > 0) {
                HashMap<String, Map<String, String>> keyValueMap = new HashMap<>();
                keyValueMap.put(Constants.REDIS_KEY_SHOP, map);
                redisStringUtils.hMSetBatch(keyValueMap, Constants.REDIS_PLATFORM_MANAGE_INDEX);
            }
        }
    }

    @Override
    public Wrapper<List<ShopVO>> shopByIdList(CommonIdListDTO request) {
        List<Shop> shopList = shopRepository.findByIdIn(request.getIdList());
        if (CollectionUtil.isEmpty(shopList)) {
            return Wrapper.success(new ArrayList<>());
        }

        List<ShopVO> collect = shopList.stream().map(a -> {
            ShopVO shopResponse = new ShopVO();
            BeanUtils.copyProperties(a, shopResponse);
            return shopResponse;
        }).collect(Collectors.toList());

        return Wrapper.success(collect);
    }

    @Override
    public Wrapper<List<ShopVO>> byShopIds(CommonIdListDTO request) {
        //由于改动较大,所以目前采用id分割来从两个表获取数据
        List<Long> minId = request.getIdList().stream().filter(a -> a <= 1000).collect(Collectors.toList());
        List<Long> maxId = request.getIdList().stream().filter(a -> a > 1000).collect(Collectors.toList());
        List<Shop> shopList = shopRepository.findByIdIn(minId);
        List<ShopVO> collect = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(shopList)) {
            collect = shopList.stream().map(a -> {
                ShopVO shopResponse = new ShopVO();
                BeanUtils.copyProperties(a, shopResponse);
                return shopResponse;
            }).collect(Collectors.toList());
        }

        List<ShopRuleDetail> shopRuleDetails = shopRuleDetailRepository.findByIdIn(maxId);
        if (CollectionUtil.isNotEmpty(shopRuleDetails)) {
            List<ShopVO> vos = shopRuleDetails.stream().map(a -> {
                ShopVO shopResponse = new ShopVO();
                BeanUtils.copyProperties(a, shopResponse);
                shopResponse.setSelf(1);
                return shopResponse;
            }).collect(Collectors.toList());
            collect.addAll(vos);
        }

        return Wrapper.success(collect);
    }

    @Override
    public Wrapper<List<ShopInnerVO>> shopByIds(CommonIdListDTO request) {
        List<Shop> shopList = shopRepository.findByIdIn(request.getIdList());
        if (CollectionUtil.isEmpty(shopList)) {
            return Wrapper.success(new ArrayList<>());
        }

        List<ShopInnerVO> collect = shopList.stream().map(a -> {
            ShopInnerVO shopResponse = new ShopInnerVO();
            BeanUtils.copyProperties(a, shopResponse);
            shopResponse.setUrl("http://" + a.getUrl() + ".lingxitest.com/");
            return shopResponse;
        }).collect(Collectors.toList());

        return Wrapper.success(collect);
    }


    @Override
    @ApiOperation(value = "商城列表（装修）")
    public Wrapper<List<Shop>> listAdorn(ShopListRequest request) {
        List<Shop> list = shopRepository.findAllByTypeAndEnvironmentAndPropertyAndState(
                request.getType(),
                request.getEnvironment(),
                request.getProperty(),
                CommonBooleanEnum.YES.getCode(),
                Sort.by("id").ascending()
        );

        if (StringUtils.isNotEmpty(request.getName())) {
            list = list.stream().filter(a -> a.getName().contains(request.getName())).collect(Collectors.toList());
        }

        return Wrapper.success(list);
    }

    @Override
    public Wrapper<Boolean> openMro(Long shopId) {
        Shop shop = shopRepository.findById(shopId).orElse(null);
        if (shop == null) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_MALL_DOES_NOT_EXIST);
        }
        return shop.getOpenMro() == CommonBooleanEnum.YES.getCode() ? Wrapper.success(true) : Wrapper.success(false);
    }

    /**
     * 采购竞价单- 根据待新增竞价单需要发布的商城类型返回商城信息
     * @param request 商城类型信息
     * @param sysUser
     */
    @Override
    public Wrapper<List<Shop>> findShopsByShopType(BiddingShopRequest request, UserLoginCacheDTO sysUser) {

        return Wrapper.success(new ArrayList<>());
    }


    @Override
    public Wrapper<List<EnterpriseShopListResponse>> listEnterpriseShopBySite (Long siteId, UserLoginCacheDTO sysUser) {
        //获取当前用户登录企业B端商城
        QShop qShop = QShop.shop;
        QSiteShop qSiteShop = QSiteShop.siteShop;
        QSite qSite = QSite.site;
        //封装企业商城
        JPAQuery<Shop> query = jpaQueryFactory.select(qShop)
                .from(qShop).leftJoin(qSiteShop).on(qShop.id.eq(qSiteShop.shopId))
                .leftJoin(qSite).on(qSite.id.eq(qSiteShop.siteId))
                .where(qSite.id.eq(siteId).and(qShop.type.eq(ShopTypeEnum.ENTERPRISE.getCode())
                        .and(qShop.state.eq(CommonBooleanEnum.YES.getCode())
                        .and(qShop.property.eq(ShopPropertyEnum.UNION_B.getCode())))));

        List<Shop> shopList = query.fetch();
        List<EnterpriseShopListResponse> responses = shopList.stream().map(shop -> {
            EnterpriseShopListResponse response = new EnterpriseShopListResponse();
            response.setId(shop.getId());
            response.setType(shop.getType());
            response.setEnvironment(shop.getEnvironment());
            response.setName(shop.getName());
            response.setProperty(shop.getProperty());
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(responses);
    }



}
